package org.linlinjava.litemall.admin.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.annotations.VisibleForTesting;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.linlinjava.litemall.admin.beans.FormulaConstants;
import org.linlinjava.litemall.admin.beans.vo.GoodsRegionVo;
import org.linlinjava.litemall.admin.dto.AdminLumierePackageDTO;
import org.linlinjava.litemall.admin.dto.AdminLumierePackageGoodsDTO;
import org.linlinjava.litemall.admin.errorcode.ErrorCodeConstants;
import org.linlinjava.litemall.admin.vo.packagegoods.*;
import org.linlinjava.litemall.core.exception.util.ServiceExceptionUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @auth :ply
 * @date 2024/6/11 14:27
 * @Description TODO
 * 管理套餐管理服务
 */
@Transactional
@Service
@RequiredArgsConstructor
public class AdminLumierePackageService {

    private final LumierePackageService lumierePackageService;

    private final LumierePackageCategoryService lumierePackageCategoryService;

    private final AdminLumierePackageCategoryService adminLumierePackageCategoryService;

    /**
     * 套餐商品服务
     */
    private final LumierePackageCategoryGoodsService lumierePackageCategoryGoodsService;

    /**
     * 目录服务
     */
    private final LitemallCategoryService categoryService;

    /**
     * 地区服务
     */
    private final LitemallGoodsRegionService regionService;

    private final LitemallShopRegionService litemallShopRegionService;

    /**
     * 商品服务
     */
    private final LitemallGoodsService goodsService;


    public Object generatePackageSn() {
        // 查询当前最大的编号
        Integer maxGoodsSn = lumierePackageService.getMaxPackageSn();
        if (maxGoodsSn == null) {
            return ResponseUtil.ok(10000); // 初始值
        }
        return ResponseUtil.ok(maxGoodsSn + 1);
    }

    public ResponseUtil.Response listLumierePackage(LumierePackage lumierePackage, Integer page, Integer limit,
                                                    Integer loginAdminShopId) {
        List<Integer> packageIdList = new ArrayList<>();
        if(loginAdminShopId!=null){
            List<LitemallGoodsRegion> goodsRegionList = new ArrayList<>();
            List<LitemallShopRegion> shopRegionList = litemallShopRegionService.queryByShopId(loginAdminShopId);
            for (LitemallShopRegion shopRegion : shopRegionList) {
                goodsRegionList.addAll(regionService.selectByCityId(shopRegion.getRegionId()));
            }
            packageIdList.addAll(CollStreamUtil.toList(goodsRegionList,LitemallGoodsRegion::getPackageId));
        }

        // 构建查询条件
        LambdaQueryWrapper<LumierePackage> queryWrapper = new LambdaQueryWrapper<>();

        Optional.ofNullable(lumierePackage.getPackageName())
                .filter(StringUtils::isNotEmpty)
                .ifPresent(name -> queryWrapper.like(LumierePackage::getPackageName, name));

        Optional.ofNullable(lumierePackage.getPackageNumber())
                .filter(StringUtils::isNotEmpty)
                .ifPresent(number -> queryWrapper.like(LumierePackage::getPackageNumber, number));

        Optional.ofNullable(lumierePackage.getCategoryId())
                .filter(categoryId -> categoryId != 0)
                .ifPresent(categoryId -> queryWrapper.eq(LumierePackage::getCategoryId, categoryId));

        Optional.ofNullable(lumierePackage.getShopId())
                .filter(shopId -> shopId != 0)
                .ifPresent(shopId -> queryWrapper.eq(LumierePackage::getShopId, shopId));
        queryWrapper.orderByDesc(LumierePackage::getIsOnSale);

        if(packageIdList.size()>0){
            queryWrapper.in(LumierePackage::getId, packageIdList);
        }
        // 执行查询
        IPage<LumierePackage> lumierePackages = lumierePackageService.page(new Page<>(page,limit),queryWrapper);

        List resultList = new ArrayList<>();
        lumierePackages.getRecords().forEach(packageCategory -> {
            LitemallCategory category = categoryService.findById(packageCategory.getCategoryId());
            AdminLumierePackageVO packageVO = new AdminLumierePackageVO();
            BeanUtils.copyProperties(packageCategory,packageVO);
            packageVO.setCategoryName(category.getName());
            resultList.add(packageVO);
        });

        // 返回结果
        lumierePackages.setRecords(resultList);
        return ResponseUtil.okPage(lumierePackages);
    }

    /**
     * 根据指定ID获取套餐详情。
     * @param id 套餐ID
     * @return 包含套餐详情的响应结果
     */
    public ResponseUtil.Response details(Integer id){
        AdminLumierePackageDTO adminLumierePackageDTO = new AdminLumierePackageDTO();

        LumierePackage lumierePackage = lumierePackageService.getById(id);

        Integer categoryId = lumierePackage.getCategoryId();
        LitemallCategory category = categoryService.findById(categoryId);
        Integer[] categoryIds = new Integer[]{};
        if (category != null) {
            Integer parentCategoryId = category.getPid();
            LitemallCategory c2 = categoryService.findById(parentCategoryId);
            categoryIds = new Integer[]{c2.getPid(), parentCategoryId, categoryId};
        }

        List<GoodsRegionVo> regions = queryPackageRegionDetail(id);

        adminLumierePackageDTO.setLumierePackage(lumierePackage);
        adminLumierePackageDTO.setCategoryIds(categoryIds);
        adminLumierePackageDTO.setRegionVos(regions);

        return ResponseUtil.ok(adminLumierePackageDTO);
    }

    /**
     * 查询货物区域细节
     *
     * @param packageId 套餐id
     * @return {@link List}<{@link GoodsRegionVo}>
     */
    private List<GoodsRegionVo> queryPackageRegionDetail(Integer packageId) {
        List<GoodsRegionVo> result = new ArrayList<>();
        List<LitemallGoodsRegion> regions = regionService.queryByPid(packageId);
        for (LitemallGoodsRegion goodsRegion : regions) {
            GoodsRegionVo goodsRegionVo = new GoodsRegionVo();
            BeanUtils.copyProperties(goodsRegion, goodsRegionVo);
            result.add(goodsRegionVo);
        }
        return result;
    }

    /**
     * 添加新的套餐。
     * @param lumierePackageDTO 待添加的套餐对象
     * @return 添加操作的响应结果
     */
    public ResponseUtil.Response addLumierePackage(AdminLumierePackageDTO lumierePackageDTO,Integer adminId,Integer shopId) {
        LumierePackage lumierePackage = lumierePackageDTO.getLumierePackage();
        lumierePackage.setShopId(shopId);
        lumierePackage.setAddTime(LocalDateTime.now());
        lumierePackage.setAddUserId(adminId.toString());
        lumierePackage.setUpdateTime(LocalDateTime.now());
        lumierePackage.setUpdateUserId(adminId.toString());

        // 设置七组LocalTime数组，每组都为23:59:59到23:59:59作为服务时间组
        List<LocalTime[]> localTimeLists = new ArrayList<>();

        for (int i = 0; i < 7; i++) {
            localTimeLists.add(new LocalTime[]{LocalTime.of(23, 59, 59), LocalTime.of(23, 59, 59)});
        }

        lumierePackage.setWeeksTime(localTimeLists);

        lumierePackageService.save(lumierePackage);

        // 创建默认的 饮品类 糕点类，并使用 forEach 遍历 🚀
        Arrays.asList("饮品类", "糕点类").forEach(categoryName -> {
            LumierePackageCategory packageCategory = LumierePackageCategory.builder()
                    .packageId(lumierePackage.getId()).categoryName(categoryName).quantity(1).build();
            adminLumierePackageCategoryService.addLumierePackageCategory(packageCategory, adminId);
        });

        LitemallGoodsRegion[] litemallGoodsRegions = lumierePackageDTO.getRegions();
        // 添加商品区域
        for (LitemallGoodsRegion goodsRegion : litemallGoodsRegions) {
            goodsRegion.setPackageId(lumierePackageDTO.getLumierePackage().getId());
            regionService.add(goodsRegion);
        }
        return ResponseUtil.ok(lumierePackageDTO.getLumierePackage().getId());
    }

    /**
     * 更新套餐信息。
     * @param lumierePackageDTO 待更新的套餐对象
     * @return 更新操作的响应结果
     */
    public ResponseUtil.Response updateLumierePackage(AdminLumierePackageDTO lumierePackageDTO) {
        LumierePackage lumierePackage = lumierePackageDTO.getLumierePackage();
        //是否已经下架才能编辑
        if(lumierePackage.getIsOnSale()){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.LUMIERE_PACKAGE_CATEGORY_GOODS_NOT_REMOVED);
        }

        lumierePackage.setCategoryId(lumierePackageDTO.getCategoryIds()[2]);
        regionService.remove(Wrappers.lambdaQuery(LitemallGoodsRegion.class).eq(LitemallGoodsRegion::getPackageId,lumierePackage.getId()));
        List<LitemallGoodsRegion> goodsRegions = Convert.convert(new TypeReference<List<LitemallGoodsRegion>>() {
        }, lumierePackageDTO.getRegionVos());
        //添加商品区域
        for (LitemallGoodsRegion goodsRegion : goodsRegions) {
            goodsRegion.setPackageId(lumierePackageDTO.getLumierePackage().getId());
            regionService.add(goodsRegion);
        }
        return lumierePackageService.updateById(lumierePackage) ? ResponseUtil.ok() : ResponseUtil.fail();
    }

    @VisibleForTesting
    private void validatePackage(Integer packageId){
        LumierePackage lumierePackage = lumierePackageService.getById(packageId);
        List<LocalTime[]> weeksTime = lumierePackage.getWeeksTime();
        if(CollUtil.isEmpty(weeksTime)){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.LUMIERE_PACKAGE_CATEGORY_GOODS_WEEK_NOT_NULL);
        }

        // 构建查询条件
        LambdaQueryWrapper<LumierePackageCategory> queryWrapper = new LambdaQueryWrapper<>();

        Optional.ofNullable(packageId)
                .filter(pid -> pid != 0) // 判断packageId是否不等于0
                .ifPresent(pid -> queryWrapper.eq(LumierePackageCategory::getPackageId, pid));
        List<LumierePackageCategory> packageCategories = lumierePackageCategoryService.list(queryWrapper);

        if(packageCategories==null || packageCategories.size()==0){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.LUMIERE_PACKAGE_CATEGORY_GOODS_DEFAULT);
        }

        //套餐商品
        List<LumierePackageCategoryGoods> packageCategoryGoodsList = lumierePackageCategoryGoodsService.list(Wrappers.lambdaQuery(LumierePackageCategoryGoods.class)
                .eq(LumierePackageCategoryGoods::getPackageId, packageId));

        for (LumierePackageCategory packageCategory : packageCategories) {
            long count = packageCategoryGoodsList.stream().filter(packageCategoryGoods -> packageCategoryGoods.getPackageCategoryId().intValue() == packageCategory.getId()).count();
            if(count == 0){
                throw ServiceExceptionUtil.exception(ErrorCodeConstants.LUMIERE_PACKAGE_CATEGORY_GOODS_DEFAULT_NUM);
            }
        }

        /*Integer packageCategoriesNum = 0;
        for (LumierePackageCategory packageCategory : packageCategories) {
            packageCategoriesNum+=packageCategory.getQuantity();
        }

        Integer packageCategoryGoodsNum = 0;
        for (LumierePackageCategoryGoods packageCategoryGoods : packageCategoryGoodsList) {
            if(packageCategoryGoods.getIsDefault()){
                packageCategoryGoodsNum+=packageCategoryGoods.getQuantity();
            }
        }
        if(packageCategoriesNum==0){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.LUMIERE_PACKAGE_CATEGORY_GOODS_DEFAULT);
        }

        if(packageCategoriesNum.intValue()!=packageCategoryGoodsNum){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.LUMIERE_PACKAGE_CATEGORY_GOODS_DEFAULT_NUM);
        }*/
    }

    /**
     * 根据指定ID删除套餐。
     * @param id 待删除的路套餐ID
     * @return 删除操作的响应结果
     */
    public ResponseUtil.Response deleteLumierePackage(Integer id){
        regionService.deleteByPid(id);
        return lumierePackageService.removeById(id) ? ResponseUtil.ok() : ResponseUtil.fail();
    }


    /**
     * 添加新的套餐商品。
     * @param reqVO 待添加的套餐商品对象
     * @return 添加操作的响应结果
     */
    public ResponseUtil.Response addPackageGoodsInfo(AdminLumierePackageGoodsSaveReqVO reqVO,Integer adminId){

        //校验套餐存在
        validatePackageCategoryGoodsExist(reqVO.getPackageId());

        //去掉其他默认
        if(reqVO.getIsDefault()){
            LambdaUpdateWrapper<LumierePackageCategoryGoods> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(LumierePackageCategoryGoods::getPackageCategoryId,reqVO.getPackageCategoryId());
            lambdaUpdateWrapper.eq(LumierePackageCategoryGoods::getPackageId,reqVO.getPackageId());
            lambdaUpdateWrapper.set(LumierePackageCategoryGoods::getIsDefault,0);
            lumierePackageCategoryGoodsService.update(lambdaUpdateWrapper);
        }

        //添加套餐商品信息
        LumierePackageCategoryGoods packageCategoryGoods = new LumierePackageCategoryGoods()
                .setId(reqVO.getId())
                .setCategoryId(reqVO.getCategoryId())
                .setPackageId(reqVO.getPackageId())
                .setPackageCategoryId(reqVO.getPackageCategoryId())
                .setGoodsId(reqVO.getGoodsId())
                .setQuantity(reqVO.getQuantity())
                //.setAmount(reqVO.getAmount())
                //.setUnit(reqVO.getUnit())
                .setIsDefault(reqVO.getIsDefault())
                //.setSpecifications(JSONUtil.toJsonStr(reqVO.getPackageSpecifications()))

                .setAddUserId(adminId.toString())
                .setUpdateUserId(adminId.toString())
                .setDeleted(false)
                .setAddTime(LocalDateTime.now())
                .setUpdateTime(LocalDateTime.now());

        //第一个都设置为默认
        if(lumierePackageCategoryGoodsService.count(Wrappers.lambdaQuery(LumierePackageCategoryGoods.class)
                .eq(LumierePackageCategoryGoods::getPackageCategoryId,reqVO.getPackageCategoryId())
                .eq(LumierePackageCategoryGoods::getPackageId,reqVO.getPackageId()))==0){
            packageCategoryGoods.setIsDefault(true);
        }

        return lumierePackageCategoryGoodsService.saveOrUpdate(packageCategoryGoods)?ResponseUtil.ok():ResponseUtil.fail();
    }

    @VisibleForTesting
    private void validatePackageCategoryGoodsExist(Integer packageId){
        //获取套餐信息
        LumierePackage lumierePackage = lumierePackageService.getById(packageId);
        if(ObjectUtil.isNull(lumierePackage)){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.LUMIERE_PACKAGE_CATEGORY_GOODS_NOT_EXIST);
        }
    }

    /**
     * 查询套餐商品列表
     * @return 套餐列表
     */
    public ResponseUtil.Response listPackageGoodsInfo(Integer packageId){
        //获取套餐信息
        LumierePackage lumierePackage = lumierePackageService.getById(packageId);
        List<AdminLumierePackageGoodsDTO> lumierePackageGoodsDTOList = JSONUtil.toList(JSONUtil.parseArray(lumierePackage.getPackageGoodsInfo()), AdminLumierePackageGoodsDTO.class);

        List<AdminLumierePackageGoodsVO> lumierePackageGoodsVOList = new ArrayList<>();

        lumierePackageGoodsDTOList.forEach(lumierePackageGoodsInfo -> {
            AdminLumierePackageGoodsVO adminLumierePackageGoodsVO = new AdminLumierePackageGoodsVO();
            Integer goodsId = lumierePackageGoodsInfo.getGoodsId();
            LitemallGoods goods = goodsService.findById(goodsId);
            BeanUtils.copyProperties(goods,adminLumierePackageGoodsVO);
            adminLumierePackageGoodsVO.setQuantity(lumierePackageGoodsInfo.getQuantity());
            lumierePackageGoodsVOList.add(adminLumierePackageGoodsVO);
        });

        return ResponseUtil.ok(lumierePackageGoodsVOList);
    }

    /**
     * 根据指定ID删除套餐商品。
     * @param packageCategoryGoodsId 待删除的套餐商品ID
     * @return 删除操作的响应结果
     */
    public ResponseUtil.Response deletePackageGoodsInfo(Integer packageCategoryGoodsId){
        return lumierePackageCategoryGoodsService.removeById(packageCategoryGoodsId) ? ResponseUtil.ok() : ResponseUtil.fail();
    }

    public ResponseUtil.Response updateOnSale(Integer id, Boolean isOnSale) {
        //校验是否符合标准
        if(isOnSale){
            validatePackage(id);
        }
        LambdaUpdateWrapper<LumierePackage> set = Wrappers.lambdaUpdate(LumierePackage.class).eq(LumierePackage::getId, id)
                .set(LumierePackage::getIsOnSale, isOnSale);
        lumierePackageService.update(set);
        return ResponseUtil.ok(true);
    }
}
